/**
 * TManFactory.java
 * ************************** 
 * @date May 5, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package gossipServices.bootstraping.tman;

import gossipServices.basic.nodeDescriptors.GeneralNodeDescriptor;
import gossipServices.basic.nodeDescriptors.NodeDescriptor;
import gossipServices.basic.view.PartialView;
import gossipServices.bootstraping.tman.rankingMethods.SortedRing;
import gossipServices.pss.PeerSamplingServiceAPI;
import networkRmi.NetworkManager;

/**
 * Description: 
 * Factory that instantiate the TMan protocol.
 * It requires a PartialView in input which will be used to initialize
 * the TMan view.
 * Following the  
 * "T-Man: Gossip-based fast overlay topology construction"
 * M. Jelasity, A. Montresor, O. Babaoglu, 2009, Computer Networks
 * we set: psi = 1, m = 20, tabuListSize = 4. 
 * Exception is the parameter k = 999 through with we select the entire
 * view each time.
 *
 */
public class TManFactory {
	
	protected static final long cycleLength = 1000; //ms 
	
	protected static final int DEFAULT_TABULIST_SIZE = 4;
	
	protected static int psi = 1; //from the paper phi = 1;
	protected static int m = 20; //from the paper m = 20;
	
	//it will define the degree of the resulting graph // k =2;
	protected static int K = 999; 
	protected int tabuListSize = 4; // from the paper tabuListSize = 4;
	
	protected TMan tman;
	protected NetworkManager nm;
	protected TManNetworkManager tmanNm;
	protected PeerSamplingServiceAPI pss;
	protected TManRankingMethod rankingMet;
	protected NodeDescriptor local;
	protected String subcloudID;

	public TManFactory(NetworkManager nm, PeerSamplingServiceAPI pss,
			PartialView initView, String subcloudID){
		initializeVariables(nm, pss, subcloudID);
		startingTMan(initView);
	}
	
	private void setSubcloudID(String subcloudID) {
		this.subcloudID = subcloudID;
	}
	
	/**
	 * @param subcloudID 
	 * @param nm2
	 * @param pss2
	 */
	private void initializeVariables(NetworkManager nm,
			PeerSamplingServiceAPI pss, String subcloudID) {
		this.nm = nm;
		this.pss = pss;
		setSubcloudID(subcloudID);
		tmanNm = new TManNetworkManager(nm, subcloudID);
		local = new GeneralNodeDescriptor(nm.getNodeName());
		rankingMet = new SortedRing(K);
	}



	public TMan getTMan(){
		return tman;
	}
	
	public void startingTMan(PartialView initView){
		int viewSize = initView.size();
		// initialization of the size of the TabuList to viewSize
		if( (viewSize > DEFAULT_TABULIST_SIZE) || (viewSize == 0) )
			tabuListSize = DEFAULT_TABULIST_SIZE;
		else
			tabuListSize = viewSize - 1;
		
		// initialization of the phi parameter to the viewSize
		if(viewSize > 0)
			psi = viewSize;
		tman = new TMan(cycleLength, initView, 
				pss, tmanNm, local, rankingMet, m, psi, tabuListSize, subcloudID);
	}

	/**
	 * @return
	 */
	public NodeDescriptor getLocalNode() {
		return local;
	}
	

}
